#import "PhysicSprite.h"
#import "GB2ShapeCache.h"


@interface PhysicSprite () {
    
}

@end


@implementation PhysicSprite


#pragma mark - Class's constructors
- (id)init {
    self = [super init];
    if (self) {
    }
    return self;
}
- (id)initWithWorld:(b2World *)world plistName:(NSString *)plistName imageName:(NSString *)imageName texture:(CCTexture2D *)texture rect:(CGRect)rect {
    self = [super initWithTexture:texture rect:rect];
    if (self) {
        [[GB2ShapeCache sharedShapeCache] addShapesWithFile:plistName];
        
        // Create physic body
        b2BodyDef bodyDef;
        bodyDef.type     = b2_dynamicBody;
        bodyDef.angle    = 0.0f;
        bodyDef.position = b2Vec2(kSize.width/2/PTM_RATIO, kSize.height/2/PTM_RATIO);
        bodyDef.userData = self;

        _body = world->CreateBody(&bodyDef);
        
        // Add the fixture definitions to the body
        [[GB2ShapeCache sharedShapeCache] addFixturesToBody:_body forShapeName:imageName];
        [self setAnchorPoint:[[GB2ShapeCache sharedShapeCache] anchorPointForShape:imageName]];
        
        // Store body's centroid
        _centroid = _body->GetLocalCenter();
    }
    return self;
}


#pragma mark - Cleanup memory
- (void)dealloc {
    b2World *world = _body->GetWorld();
    world->DestroyBody(_body);
    
    [super dealloc];
}


#pragma mark - Class's properties
- (BOOL)dirty {
    return YES;
}
- (CGAffineTransform)nodeToParentTransform {
    b2Vec2  pos = _body->GetPosition();
    CGFloat x = pos.x * PTM_RATIO;
    CGFloat y = pos.y * PTM_RATIO;
    
    if (!ignoreAnchorPointForPosition_) {
        x += anchorPointInPoints_.x;
        y += anchorPointInPoints_.y;
    }
    
    // Make matrix
    CGFloat radians = _body->GetAngle();
    CGFloat c = cosf(radians);
    CGFloat s = sinf(radians);
    if(!CGPointEqualToPoint(anchorPointInPoints_, CGPointZero)) {
        x += (c * -anchorPointInPoints_.x) + (-s * -anchorPointInPoints_.y);
        y += (s * -anchorPointInPoints_.x) + (c * -anchorPointInPoints_.y);
    }
    
    // Rotate, Translate Matrix
    transform_ = CGAffineTransformMake(c, s, -s, c, x, y);
    return transform_;
}

- (void)setRotation:(float)rotation {
    b2Vec2  pos = _body->GetPosition();
    CGFloat x = pos.x * PTM_RATIO;
    CGFloat y = pos.y * PTM_RATIO;
    
    if (!ignoreAnchorPointForPosition_) {
        x += anchorPointInPoints_.x;
        y += anchorPointInPoints_.y;
    }
    _body->SetTransform(_body->GetPosition(), rotation * DEG_TO_RAD);
}
- (void)setPosition:(CGPoint)position {
    [super setPosition:position];
    _body->SetTransform(b2Vec2(position.x / PTM_RATIO, position.y / PTM_RATIO), _body->GetAngle());
}


#pragma mark - Class's public methods
- (void)setLinearVelocity:(b2Vec2)velocity {
    _body->SetLinearVelocity(velocity);
}


#pragma mark - Class's private methods


#pragma mark - Class's notification handlers


@end
